package com.ttk.issuetracker.service;

import java.util.List;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ttk.issuetracker.model.TaskLog;
import com.ttk.issuetracker.model.User;
import com.ttk.issuetracker.vo.Result;
import com.ttk.issuetracker.vo.ResultFactory;

public class UserServiceImpl extends AbstractService implements UserService {

	@Override
	public Result<User> store(String username, String firstName,
			String lastName, String email, String password,
			String adminRole, String actionUsername) {
		User currentUser = userDao.findByUsername(actionUsername);
		if(currentUser == null) {
			return ResultFactory.getFailResult(USER_INVALID);
		} else if(!currentUser.isAdmin()) {
			return ResultFactory.getFailResult(USER_NOT_ADMIN);
		}
		
		//check null
		if(username == null || email == null || password == null) {
			return ResultFactory.getFailResult("Field cannot be null");
		}
		
		//check empty
		if(username.trim().length() == 0 || email.trim().length() ==0
				|| password.trim().length() == 0) {
			return ResultFactory.getFailResult("Field cannot be empty");
		}
		
		User findByEmail = userDao.findByEmail(email.toLowerCase());
		User user = userDao.findByUsername(username);
		if(user == null) {
			if(findByEmail == null) {
				user = new User();
				user.setUsername(username);
				user.setEmail(email);
			} else {
				return ResultFactory.getFailResult("This is email [" + email + "] being used by somebody");
			}
		} else {
			if(findByEmail == null) {
				user.setEmail(email);
			} else if(!user.equals(findByEmail)){
				return ResultFactory.getFailResult("This is email used by [" + findByEmail + "]");
			}
		}
		 
		user.setAdminRole(adminRole);
		user.setFirstName(firstName);
		user.setLastName(lastName);
		user.setPassword(password);
		
		if(user.getId() == null) {
			userDao.persist(user);
		} else {
			userDao.merge(user);
		}
		
		return ResultFactory.getSuccessResult(user);
	}

	@Transactional(readOnly=false, propagation=Propagation.REQUIRED)
	@Override
	public Result<User> remove(String username, String actionUsername) {
		User actionUser = userDao.findByUsername(actionUsername);
        if (!actionUser.isAdmin()) {
            return ResultFactory.getFailResult(USER_NOT_ADMIN);
        }
		if(username == null) {
			return ResultFactory.getFailResult("Unable to remove user with username = ["+ username +"]");
		}
		
		User user = userDao.findByUsername(username);
		if(user == null) {
			return ResultFactory.getFailResult("Unable to find user with username = ["+ username +"]");
		}
		
		List<TaskLog> taskLogs = user.getTaskLogs();
		if(taskLogs.size() > 0) {
			return ResultFactory.getFailResult("Unable to remove user that has taskLog assigned");
		} else {
			userDao.remove(user);
			return ResultFactory.getSuccessResultMsg("Remove user with username [" + username + "] successful");
		}
	}

	@Transactional(readOnly=true, propagation=Propagation.SUPPORTS)
	@Override
	public Result<User> find(String username, String actionUsername) {
		if(!isValidUser(actionUsername)) {
			return ResultFactory.getFailResult(USER_INVALID);
		}
		
		if(username == null) {
			return ResultFactory.getFailResult("Unable to remove user with username = ["+ username +"]");
		}
		
		User user = userDao.findByUsername(username);
		if(user == null) {
			return ResultFactory.getFailResult("Unable to find user with username = ["+ username +"]");
		} else {
			return ResultFactory.getSuccessResult(user);
		}
	}

	@Transactional(readOnly=true, propagation=Propagation.SUPPORTS)
	@Override
	public Result<List<User>> findAll(String actionUsername) {
		if(!isValidUser(actionUsername)) {
			return ResultFactory.getFailResult(USER_INVALID);
		}
		
		List<User> users = userDao.findAll();
		if(users == null) {
			return ResultFactory.getFailResult("Unable to find all user.");
		} else {
			return ResultFactory.getSuccessResult(users);
		}
	}

	@Transactional(readOnly=true, propagation=Propagation.SUPPORTS)
	@Override
	public Result<User> findByUsernamePassword(String username, String password) {
		if(username == null) {
			return ResultFactory.getFailResult("Unable to find user with username = ["+ username +"]");
		} else if(password == null) {
			return ResultFactory.getFailResult("Unable to find user with password = ["+ password +"]");
		} else {
			User user = userDao.findByUsernamePassword(username, password);
			if(user == null) {
				return ResultFactory.getFailResult("Unable to find user with username = ["+ username +"], password = ["+ password +"]");
			} else {
				return ResultFactory.getSuccessResult(user);
			}
		}
	}
}
